package com.hp.bon.sgw.wh.channel.handler;

import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.Constants.MessageType;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.BuzProcessorManager;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.channel.SoapChannel;
import com.hp.bon.sgw.core.channel.handler.IAsynCallHandler;
import com.hp.bon.sgw.domain.MessageDetail;
import com.hp.bon.sgw.threads.MessageDetailCacheManager;
import com.hp.bon.sgw.threads.TaskManager;
import com.hp.bon.sgw.wh.Constants.AliParam;
import com.hp.bon.sgw.wh.service.WHConfigService;
import com.hp.bon.sgw.wh.utils.DESCryptoUtil;
import com.hp.bon.sgw.wh.utils.SignUtilsImpl;
import com.hp.ocs.diameter.message.Message;

public class SignTaobaoHandler implements IAsynCallHandler {
	
	private static final Logger logger = LoggerFactory.getLogger(SignTaobaoHandler.class);
	private PrintStream printStream;
	private WHConfigService whConfigService;
	private String msgId;
	
	public SignTaobaoHandler(PrintStream printStream, String msgId, WHConfigService whConfigService){
		this.printStream = printStream;
		this.whConfigService = whConfigService;
		this.msgId = msgId;
	}
	
	@Override
	public void onCallResult(CallParam callParam) {
		XmlMessage ack = null;
		Object response = null;

		if (callParam.getResponse() != null) {
			response = callParam.getResponse();
		} else if (callParam.getRecvResponse() != null) {
			response = callParam.getRecvResponse();
		}

		if (response == null) {
			ack = SoapChannel.createERRAnwser(callParam.getSessionId(),
					callParam.getRetCode() == 3002 ? 11202 : callParam.getRetCode(), callParam.getResultMsg());
		} else {
			if (response instanceof Message) {// CCA -> XML
				ack = BuzProcessorManager.getInstance().convertMessageToAck(callParam);
			} else if (response instanceof XmlMessage) {
				ack = (XmlMessage) response;
			} else {
				logger.warn("unknown response type:"+ callParam.getResponse().getClass().getName());
			}
		}
		try {
			String respXML = TaobaoConvertResponseString(ack);
			byte[] resp = respXML.getBytes("UTF-8");
			ack.setLength(resp.length);
			ack.setMsgTime(System.currentTimeMillis());
			printStream.write(resp);
			printStream.close();

			callParam.setResponse(ack);

			if (callParam.getRetCode() == Constants.ResultCode.SUCCESS) {// 成功的消息，请求应答入库

				MessageDetail detail = new MessageDetail();
				detail.setBusinessCallId(callParam.getBussinessCallId());
				detail.setSessionId(callParam.getSessionId());
				detail.setServiceContextId(callParam.getServiceContextId());
				detail.setMessageType(MessageType.WSA);
				detail.setDetails(ack.getDATA());
				detail.setMsgTime(new Date(ack.getMsgTime()));
				detail.setOpType("send");
				detail.setHostId(callParam.getUserName());
				MessageDetailCacheManager.getInstance().add(detail);
			}

			TaskManager.taskProcess(callParam);
			if (logger.isInfoEnabled()) {
				logger.info("http response(taobao) " + respXML);
			}

		} catch (Exception e) {
			logger.info("Exception is :"+e);
		}
	}
	
	// 淘宝SOAP
	protected String TaobaoConvertResponseString(XmlMessage ack) {
		
		String priKeyValue = whConfigService.getValue(AliParam.priKeyValue, "");
		String pubKeyValue = whConfigService.getValue(AliParam.pubKeyValue, "");
		String algorithm = whConfigService.getValue(AliParam.algorithm, "SHA1withRSA");
		
		String respXML = null;
		StringBuilder respBody = new StringBuilder();
		String signTag = null;
		
		String rspUserNumber = null;
		String rspOperatorUserId = null;
		String rspAlertValue = null;
		String rspStatus = null;
		String rspFailedCode = null ;
		String rspFailedReason = null ;
		
		String orinData = ack.getDATA();
		if (orinData != null) {
			Document doc = null;
			try {
				doc = DocumentHelper.parseText(orinData);
				Element root = doc.getRootElement();

				Node node = root.selectSingleNode("//Service_Information/Acc_Nbr");
				if (node != null) {
					rspUserNumber = node.getStringValue();
				}
				node = root.selectSingleNode("//Service_Information/alertValue");
				if (node != null) {
					rspAlertValue = node.getStringValue();
				}
				node = root.selectSingleNode("//Service_Information/ServId");
				if (node != null) {
					rspOperatorUserId = node.getStringValue();
				}
				node = root.selectSingleNode("//Service_Information/Status");
				if (node != null) {
					rspStatus = node.getStringValue();
				}
				node = root.selectSingleNode("//Service_Information/failedCode");
				if (node != null) {
					rspFailedCode = node.getStringValue();
				}
				node = root.selectSingleNode("//Service_Information/failedReason");
				if (node != null) {
					rspFailedReason = node.getStringValue();
				}
			} catch (DocumentException e1) {
				logger.info("Document Exception :"+e1);
			}
		}
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hh:mm:ss") ;
		Date date = new Date(System.currentTimeMillis());
		StringBuilder sb = new StringBuilder();
		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>")
				.append("<message>")
				.append("<head>")
				.append("<version>").append("1.0.1").append("</version>")
				.append("<instId>").append("HBTELECOM").append("</instId>")
				.append("<type>SignRes</type>")
				.append("<msgId>").append(msgId).append("</msgId>")
				.append("<msgTime>").append(sdf.format(date)).append("</msgTime>")
				.append("<secId>").append("0002").append("</secId>")
				.append("</head>")
				.append("<body>")
				.append("<userNumber>").append(rspUserNumber).append("</userNumber>")
				.append("<operatorUserId>").append(rspOperatorUserId).append("</operatorUserId>")
				.append("<alertValue>").append(rspAlertValue).append("</alertValue>")
				.append("<status>").append(rspStatus).append("</status>")
				.append("<failedCode>").append(rspFailedCode).append("</failedCode>")
				.append("<failedReason>").append(rspFailedReason).append("</failedReason>")
				.append("</body>");
		
		//如果字段中有空格，要trim掉
		respBody.append(rspUserNumber.trim()).append(rspOperatorUserId.trim()).append(rspAlertValue.trim()).append(rspStatus.trim()).append(rspFailedCode.trim()).append(rspFailedReason.trim());
		signTag = SignUtilsImpl.sign(respBody.toString(), priKeyValue, algorithm ,"UTF-8");
		
		sb.append("<signTag>").append(signTag).append("</signTag>")
		   .append("</message>") ;
		
		logger.info("response to taobao :"+sb.toString());
		
		respXML = DESCryptoUtil.encrypt(sb.toString(),pubKeyValue,null) ;
		
		return respXML;
	}
	
	@Override
	public int getProtocolType() {
		// TODO Auto-generated method stub
		return 0;
	}

}
